package com.sure.common.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.sure.common.cache.clazz.POReflectManager;
import com.sure.common.cache.clazz.model.ClassReflect;
import com.sure.common.cache.clazz.model.ColumnReflect;
import com.sure.common.exception.SystemException;

/**
 * BaseDao实现
 * @author Sure
 *
 */
public class BaseDaoImpl extends JdbcDaoSupport implements BaseDao {
	
	private static final Logger logger = Logger.getLogger(BaseDaoImpl.class);
	@Override
	public void save(Object entity) throws SystemException {
		if(null == entity) {
			throw new SystemException("新增实体为空值NULL");
		}
		ClassReflect reflect = POReflectManager.get(entity.getClass());
		//生成INSERT SQL
		//INSERT INTO emp(id,name,salary) VALUES(?,?,?);
		StringBuffer sql = new StringBuffer();
		sql.append("INSERT INTO ")
		   .append(reflect.getTableName())
		   .append("(");
		
		List<Object> params = new ArrayList<Object>();
		StringBuffer columns = new StringBuffer();
		StringBuffer values = new StringBuffer();
		
		//遍历所有字段，如果字段值不为空，则拼如sql
		for(Entry<String, ColumnReflect> entry : reflect.getColumnsMap().entrySet()) {
			ColumnReflect col = entry.getValue();
			//通过反射执行getMethod得到字段值
			Object res = null;
			try {
				res = col.getGetMethod().invoke(entity,(Object[])null);
			} catch (Exception e) {
				StringBuffer msg = new StringBuffer();
				msg.append("类【").append(entity.getClass().getName())
					.append("】中方法【").append(col.getGetMethod().getName()).append("】执行异常");
				throw new SystemException(msg.toString(),e);
			}
			
			if(null != res) {
				//字段有值
				columns.append(col.getColumnName()).append(",");
				values.append("?,");
				params.add(res);
			}
		}
		
		if(null != columns && !"".equals(columns.toString())) {
			//去掉最后一个,
			sql.append(columns.substring(0, columns.length()-1));
			sql.append(") ");
			sql.append("VALUES(");
			sql.append(values.substring(0, values.length()-1));
			sql.append(")");
		}
		logger.info("INSERT SQL："+sql.toString());
		logger.info("对应参数："+params);
		//使用spring jdbc做保存操作
		try {
			getJdbcTemplate().update(sql.toString(), params.toArray());
		} catch(DataAccessException e) {
			throw new SystemException("新增数据失败",e);
		}
	}

	@Override
	public void update(Object entity) throws SystemException {
		//UPDATE emp SET ename='sure',job='programmer' WHERE empno=7999;
		if(null == entity) {
			throw new SystemException("更新实体为空值NULL");
		}
		ClassReflect reflect = POReflectManager.get(entity.getClass());
		StringBuffer sql = new StringBuffer();
		sql.append("UPDATE ").append(reflect.getTableName()).append(" SET ");
		
		//判断主键是否都有值，如果有值，将作为更新的条件
		StringBuffer caseSql = null;
		List<Object> caseParams = null;
		for(String key : reflect.getPrimaryKeys()) {
			ColumnReflect colKey = reflect.getColumnsMap().get(key);
			if(null != colKey) {
				Object val = null;
				try {
					val = colKey.getGetMethod().invoke(entity,(Object[])null);
				} catch(Exception e) {
					StringBuffer msg = new StringBuffer();
					msg.append("类【").append(entity.getClass().getName())
						.append("】中方法【").append(colKey.getGetMethod().getName()).append("】执行异常");
					throw new SystemException(msg.toString(),e);
				}
				if(null == val || "".equals(val)) {
					//主键没有赋值
					StringBuffer msg = new StringBuffer();
					msg.append("类【").append(entity.getClass().getName())
						.append("】中，主键列【").append(key).append("】没有赋值");
					throw new SystemException(msg.toString());
				} else {
					if(null == caseSql) {
						caseSql = new StringBuffer();
					}
					if(null == caseParams) {
						caseParams = new ArrayList<Object>();
					}
					caseSql.append(key).append("=? AND ");
					caseParams.add(val);
				}
			} else {
				StringBuffer msg = new StringBuffer();
				msg.append("类【").append(entity.getClass().getName())
					.append("】中，不存在主键列【").append(key).append("】反射信息");
				throw new SystemException(msg.toString());
			}
		}

		//caseSql = caseSql.subString(0, caseSql.length()-5);

		//遍历所有字段，如果字段值不为空，则拼入更新sql
		StringBuffer updateSql = new StringBuffer();
		List<Object> updateParam = new ArrayList<Object>();
		for(Entry<String, ColumnReflect> entry : reflect.getColumnsMap().entrySet()) {
			ColumnReflect col = entry.getValue();
			//如果是主键，则无需更新
			if(reflect.getPrimaryKeys().contains(col.getColumnName())) {
				continue;
			}
			//通过反射执行getMethod得到字段值
			Object res = null;
			try {
				res = col.getGetMethod().invoke(entity,(Object[])null);
			} catch (Exception e) {
				StringBuffer msg = new StringBuffer();
				msg.append("类【").append(entity.getClass().getName())
					.append("】中方法【").append(col.getGetMethod().getName()).append("】执行异常");
				throw new SystemException(msg.toString(),e);
			}
			
			if(null != res) {
				//字段有值
				updateSql.append(col.getColumnName()).append("=?, ");
				updateParam.add(res);
			}
		}
		//更新字段信息
		sql.append(updateSql.substring(0, updateSql.length()-2));
		//更新条件信息
		if(null != caseSql) {
			sql.append(" WHERE ").append(caseSql.substring(0, caseSql.length()-4));
		} else {
			throw new SystemException("无更新条件信息，更新失败。");
		}
		//参数信息合并
		updateParam.addAll(caseParams);
		
		logger.info("UPDATE SQL："+sql);
		logger.info("更新参数："+updateParam);
		
		//执行sql
		try {
			getJdbcTemplate().update(sql.toString(), updateParam.toArray());
		} catch(DataAccessException e) {
			throw new SystemException("更新数据失败",e);
		}
		
	}

	@Override
	public void delete(Object entity) throws SystemException {
		// DELETE FROM emp WHERE emp.empno=7999;
		if(null == entity) {
			throw new SystemException("删除的实体为空值NULL");
		}
		ClassReflect reflect = POReflectManager.get(entity.getClass());
		StringBuffer sql = new StringBuffer();
		sql.append("DELETE FROM ").append(reflect.getTableName());
		
		//判断主键是否都有值，如果有值，将作为更新的条件
		StringBuffer caseSql = null;
		List<Object> caseParams = null;
		for(String key : reflect.getPrimaryKeys()) {
			ColumnReflect colKey = reflect.getColumnsMap().get(key);
			if(null != colKey) {
				Object val = null;
				try {
					val = colKey.getGetMethod().invoke(entity,(Object[])null);
				} catch(Exception e) {
					StringBuffer msg = new StringBuffer();
					msg.append("类【").append(entity.getClass().getName())
						.append("】中方法【").append(colKey.getGetMethod().getName()).append("】执行异常");
					throw new SystemException(msg.toString(),e);
				}
				if(null == val || "".equals(val)) {
					//主键没有赋值
					StringBuffer msg = new StringBuffer();
					msg.append("类【").append(entity.getClass().getName())
						.append("】中，主键列【").append(key).append("】没有赋值");
					throw new SystemException(msg.toString());
				} else {
					if(null == caseSql) {
						caseSql = new StringBuffer();
					}
					if(null == caseParams) {
						caseParams = new ArrayList<Object>();
					}
					caseSql.append(key).append("=? AND ");
					caseParams.add(val);
				}
			} else {
				StringBuffer msg = new StringBuffer();
				msg.append("类【").append(entity.getClass().getName())
					.append("】中，不存在主键列【").append(key).append("】反射信息");
				throw new SystemException(msg.toString());
			}
		}
		
		//删除条件
		if(null != caseSql) {
			sql.append(" WHERE ");
			sql.append(caseSql.substring(0, caseSql.length()-4));
		} else {
			throw new SystemException("无删除条件信息，删除失败。");
		}
		logger.info("DELETE SQL："+sql);
		logger.info("对应参数："+caseParams);
		//spring jdbc执行删除操作
		try {
			getJdbcTemplate().update(sql.toString(),caseParams.toArray());
		} catch(DataAccessException e) {
			throw new SystemException("删除失败",e);
		}
		
	}

}
